package br.uff.mic1.model;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;

public class MemoriaPrincipal {

	public final static int NUMERO_ENDERECOS = 4096;
	public static final int PALAVRAS_POR_BLOCO = 4;
	
	private String[] memoria = new String[MemoriaPrincipal.NUMERO_ENDERECOS];
	
	
	
	public void carregaPrograma(String programa)
	{
		for(int i = 0; i < memoria.length; i++)
			memoria[i] = "0000000000000000";
			
		try 
		{
			Scanner arquivo = new Scanner(new FileInputStream(programa));		
			int i = 0;
			while(arquivo.hasNextLine()) 
			{
				memoria[i] = arquivo.nextLine();
				i++;
			}
		} 
		catch(FileNotFoundException e) 
		{
			System.out.println("Arquivo do programa nao localizado.");
		}	
	}
	
	public String getPalavra(String endereco)
	{
		int address = Integer.parseInt(endereco, 2);
		
		if (address < 0 || address > MemoriaPrincipal.NUMERO_ENDERECOS-1)
			throw new IllegalArgumentException("Endereco de memoria inexistente");
		
		return this.memoria[address];
	}
	
	public void setPalavra(String endereco, String valor)
	{
		int address = Integer.parseInt(endereco, 2);
		
		if (address < 0 || address > MemoriaPrincipal.NUMERO_ENDERECOS-1)
			throw new IllegalArgumentException("Endereco de memoria inexistente");
		
		this.memoria[address] = valor;
	}
	
	//public void setBloco
	
	public void setBloco(String enderecoDeMemoria, String[] bloco)
	{
		int index = Integer.parseInt(enderecoDeMemoria, 2);
		int primeiraPosicaoDoBloco = (int) (Math.floor(index/MemoriaPrincipal.PALAVRAS_POR_BLOCO)*MemoriaPrincipal.PALAVRAS_POR_BLOCO);
		
		if (primeiraPosicaoDoBloco > MemoriaPrincipal.NUMERO_ENDERECOS-MemoriaPrincipal.PALAVRAS_POR_BLOCO || primeiraPosicaoDoBloco < 0)
			throw new IllegalArgumentException("Nao foi possivel acessar o bloco "+index);
		
		if (bloco.length > MemoriaPrincipal.PALAVRAS_POR_BLOCO)
			throw new IllegalArgumentException("Bloco grande demais");
		
		for (int i=0; i < MemoriaPrincipal.PALAVRAS_POR_BLOCO; i++)
			this.memoria[primeiraPosicaoDoBloco++] = bloco[i];
		
	}
	
	public String[] getBloco(int index)
	{
		int primeiraPosicaoDoBloco = (int) (Math.floor(index/MemoriaPrincipal.PALAVRAS_POR_BLOCO)*MemoriaPrincipal.PALAVRAS_POR_BLOCO);
		
		if (primeiraPosicaoDoBloco > MemoriaPrincipal.NUMERO_ENDERECOS-MemoriaPrincipal.PALAVRAS_POR_BLOCO || primeiraPosicaoDoBloco < 0)
			throw new IllegalArgumentException("Nao foi possivel acessar o bloco "+index);
		
		String[] retorno = new String[MemoriaPrincipal.PALAVRAS_POR_BLOCO];
		for (int i=0; i < MemoriaPrincipal.PALAVRAS_POR_BLOCO; i++)
			retorno[i] = this.memoria[index++];
		
		return retorno;
	}

	@Override
	public String toString() {
		StringBuffer s = new StringBuffer();
		s.append("Memoria Principal\n");
		for (int i = 0; i < MemoriaPrincipal.NUMERO_ENDERECOS; i++)
			s.append("\n["+i+"] "+this.memoria[i]);
		return s.toString();
	}
	
	
}
